package com.lbank.spiderflow.core.executor.shape;

import groovy.lang.Binding;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lbank.spiderflow.context.SpiderContext;
import com.lbank.spiderflow.core.utils.ExpressionUtils;
import com.lbank.spiderflow.executor.ShapeExecutor;
import com.lbank.spiderflow.model.Shape;
import com.lbank.spiderflow.model.SpiderNode;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 函数执行器
 * @author Administrator
 *
 */
@Component
public class CodeExecutor implements ShapeExecutor{
	
	public static final String SCRIPT_CODE = "scriptCode";

	public static final String LANG_TYPE = "langType";

	private static final Logger logger = LoggerFactory.getLogger(CodeExecutor.class);
	
	@Override
	public void execute(SpiderNode node, SpiderContext context, Map<String,Object> variables) {
		String langType = node.getStringJsonValue(CodeExecutor.LANG_TYPE);
		String scriptCode = node.getStringJsonValue(SCRIPT_CODE);
		if(StringUtils.isEmpty(scriptCode)){return ;}
		// 编码
		//byte[] base64Bytes = Base64.getDecoder().decode(scriptCode);
		// byte[] 转 String（解码后的字符串）
		//scriptCode = new String(base64Bytes, StandardCharsets.UTF_8);
		if ("groovy".equals(langType)) {
			String commonUtils = """
					import java.util.*;
					import com.lbank.spiderflow.core.utils.*;
					import org.apache.commons.lang3.StringUtils;
					import org.jsoup.nodes.*;
					import org.jsoup.Jsoup;
					import org.jsoup.select.*;
					""";
			scriptCode = commonUtils + scriptCode;
			Binding binding = new Binding();
			Class<?> compiledClass = GroovyScriptManager.getAndCachedScript(scriptCode);
			try {
				binding.setVariable("ctx", variables);
				Object result = GroovyScriptManager.run(compiledClass, binding);
				logger.debug("Groovy Script result: " + result);
			} catch (Exception e) {
				throw new RuntimeException(e);
			} finally {
				binding.getVariables().clear();
			}
		} else {
			if (!"javascript".equals(langType)) {
				throw new IllegalArgumentException("不支持" + langType+ "语言");
			}
			try {
				Object result = ExpressionUtils.execute(scriptCode, variables);
				logger.debug("JavaScript Script result: " + result);
			} catch (Exception e) {
				System.out.println("执行js脚本错误: " + e.getMessage());
			}
		}
	}

	@Override
	public String supportShape() {
		return "code";
	}

	@Override
	public Shape shape() {
		Shape shape = new Shape();
		shape.setImage("");
		shape.setName("code");
		shape.setTitle("code");
		shape.setLabel("code");
		shape.setDesc("自定义代码编辑器支持groovy和js脚本");
		return shape;
	}
}
